define(function(require, export)
{
    /*
      a event queue to store event like system or user defined.
     */

    //key code
    export.KEY_UP = 38;
    export.KEY_DOWN = 40;
    export.KEY_RIGHT = 39;
    export.KEY_LEFT = 37;

    export.KEY_SPACE = 32;
    export.KEY_TAB = 9;
    export.KEY_ENTER = 13;
    export.KEY_CTRL = 17;
    export.KEY_ALT = 18;
    export.KEY_ESC = 27;

    export.K_0 = 48;
    export.K_1 = 49;
    export.K_2 = 50;
    export.K_3 = 51;
    export.K_4 = 52;
    export.K_5 = 53;
    export.K_6 = 54;
    export.K_7 = 55;
    export.K_8 = 56;
    export.K_9 = 57;
    export.K_A = 65;
    export.K_B = 66;
    export.K_C = 67;
    export.K_D = 68;
    export.K_E = 69;
    export.K_F = 70;
    export.K_G = 71;
    export.K_H = 72;
    export.K_I = 73;
    export.K_J = 74;
    export.K_K = 75;
    export.K_L = 76;
    export.K_M = 77;
    export.K_N = 78;
    export.K_O = 79;
    export.K_P = 80;
    export.K_Q = 81;
    export.K_R = 82;
    export.K_S = 83;
    export.K_T = 84;
    export.K_U = 85;
    export.K_V = 86;
    export.K_W = 87;
    export.K_X = 88;
    export.K_Y = 89;
    export.K_Z = 90;
    
    //event type
    export.ON_QUIT = 0;
    export.ON_KEY_DOWN = 1;
    export.ON_KEY_UP = 2;
    export.ON_MOUSE_MOVE = 3;
    export.ON_MOUSE_UP = 4;
    export.ON_MOUSE_DOWN = 5;
    export.ON_MOUSE_DRAG = 6;

    var EVENT_QUEUE = [];

    export.dequeue = function()
    {
        return EVENT_QUEUE.shift();
    }
    
    export.enqueue = function(userEvent)
    {
        EVENT_QUEUE.push(userEvent);
    }

    export.empty = function()
    {
        return EVENT_QUEUE.length == 0;
    }

    var CALLBACK = [];

    export.register = function(callback)
    {
        CALLBACK.push(callback);
    }

    export.unregister = function(callback)
    {
        CALLBACK.filter(function(item, index){
            if(item !== callback)
            {
                return true;
            }
            return false;
        });
    }

    export.dispatch = function()
    {
        EVENT_QUEUE.forEach(function(item){
            CALLBACK.forEach(function(callback){
                callback(item);
            });
        });

        EVENT_QUEUE = [];
    }

    export.Event = function()
    {
        //Type of the event, e.g., KEYDOWN or KEYUP
        this.type = null;

        //Key code 
        this.key = null;

        //Mouse button, left or right
        this.button = null;

        //Mouse pos
        this.pos = null;
    }
       
    export.init = function()
    {
        function onKeyDown(evt)
        {
            var key = evt.keyCode || evt.which; 
            EVENT_QUEUE.push({
                'type' : export.ON_KEY_DOWN,
                'key' : key,
                'shiftKey' : evt.shiftKey,
                'ctrlKey' : evt.ctrlKey,
                'altKey' : evt.altKey
            });

            if(!evt.ctrlKey && !evt.altKey && !evt.shiftKey &&
               (key >= export.KEY_LEFT && key <= export.KEY_DOWN
                || key >= export.KEY_0 && key <= export.KEY_Z
                || key === export.KEY_SPACE
                || key === export.KEY_TAB
                || key === export.KEY_ENTER))
            {
                evt.preventDefault();
            }
        }

        function onKeyUp(evt)
        {
            EVENT_QUEUE.push({
                'type' : export.ON_KEY_UP,
                'key' : evt.keyCode || evt.which,
                'shiftKey' : evt.shiftKey,
                'ctrlKey' : evt.ctrlKey,
                'altKey' : evt.altKey
            });
        }

        var bLeftMouseDown = false;

        function onMouseMove(evt)
        {
            var currentPos = [evt.clientX, evt.clientY];
            var eventType = null;
            if(bLeftMouseDown)
            {
                eventType = export.ON_MOUSE_DRAG;
            }
            else
            {
                eventType = export.ON_MOUSE_MOVE;
            }

            EVENT_QUEUE.push({
                'type' : eventType,
                'pos' : currentPos,
                'button' : evt.button
            });
        }

        function onMouseDown(evt)
        {
            var currentPos = [evt.clientX, evt.clientY];
            
            EVENT_QUEUE.push({
                'type' : export.ON_MOUSE_DOWN,
                'pos' : currentPos,
                'button' : evt.button
            }); 
            if(evt.button == 0)
            {
                bLeftMouseDown = true;
            }
        }

        function onMouseUp(evt)
        {
            var currentPos = [evt.clientX, evt.clientY];
            
            EVENT_QUEUE.push({
                'type' : export.ON_MOUSE_UP,
                'pos' : currentPos,
                'button' : evt.button
            });
            if(evt.button == 0)
            {
                bLeftMouseDown = false;
            }
        }

        document.addEventListener('keydown', onKeyDown, false);
        document.addEventListener('keyup', onKeyUp, false);
        document.addEventListener('mousemove', onMouseMove, false)
        document.addEventListener('mousedown', onMouseDown, false);
        document.addEventListener('mouseup', onMouseUp, false);
      
    }
});